﻿using System;
using System.Web;
using NHibernate;
using NHibernate.Cfg;

namespace SNARF.Framework.ActiveRecord
{
    public sealed class WebSessionProvider : SessionProviderBase
    {
        private const string CurrentSessionKey = "SNARF.Framework.ActiveRecord.CurrentSession";
        
        public event EventHandler SessionClosing;

        public WebSessionProvider() : base()
        {
            HttpContext.Current.ApplicationInstance.EndRequest += new EventHandler(ApplicationInstance_EndRequest);
        }

        void ApplicationInstance_EndRequest(object sender, EventArgs e)
        {
            if (this.SessionClosing != null)
                this.SessionClosing(this, e);

            SessionManager.CurrentSession.Close();
        }

        public override ISession CurrentSession
        {
            get
            {
                HttpContext context = HttpContext.Current;
                
                ISession currentSession = context.Items[CurrentSessionKey] as ISession;

                if (currentSession == null)
                {
                    currentSession = sessionFactory.OpenSession();
                    currentSession.FlushMode = FlushMode.Never;
                    context.Items[CurrentSessionKey] = currentSession;                    
                }

                return currentSession;
            }
        }

        public void CloseSession()
        {
            HttpContext context = HttpContext.Current;
            ISession currentSession = context.Items[CurrentSessionKey] as ISession;

            if (currentSession == null)
            {
                // No current session
                return;
            }

            currentSession.Close();
            context.Items.Remove(CurrentSessionKey);
        }

        public void CloseSessionFactory()
        {
            if (sessionFactory != null)
            {
                sessionFactory.Close();
            }
        }
    }
}
